{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "87c6f9ba",
   "metadata": {},
   "source": [
    "-----\n",
    "* 学习人：李许娣\n",
    "* 时间：2021.11.29\n",
    "* 周：第14周\n",
    "-----"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "698b8395",
   "metadata": {},
   "source": [
    "## 本周学习目标\n",
    "* 函数的含义\n",
    "* 如何使用函数\n",
    "* 函数的参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "0f8ae960",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 \n"
     ]
    }
   ],
   "source": [
    "a,b = 0,1\n",
    "while a <10:\n",
    "    print(a, end=' ')\n",
    "    a, b = b, a+b\n",
    "    \n",
    "print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8bc3f8a9",
   "metadata": {},
   "source": [
    "> 1. 定义函数的一般方法\n",
    "  * def function_name(): # 1.function_name 遵循变量名称定义的规则 区别数学函数==> f(x) python的函数可以自定义名称\n",
    "  * \"\"\"函数的注释\"\"\" # 2.函数的注释可以和使用者交流\n",
    "  * 函数体  # 3.函数体要和定义函数保持一定的tab缩进"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "c15ae05a",
   "metadata": {},
   "outputs": [],
   "source": [
    "def fib(n):    # write Fibonacci series up to n\n",
    "    \"\"\"Print a Fibonacci series up to n.\"\"\"\n",
    "    a,b = 0,1\n",
    "    while a < n:\n",
    "        print(a, end=' ')\n",
    "        a, b = b, a+b\n",
    "    print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "e3af9841",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 13 21 34 55 89 \n"
     ]
    }
   ],
   "source": [
    "fib(100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "5fef15ac",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 13 21 34 \n"
     ]
    }
   ],
   "source": [
    "fib(45)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "2d872c09",
   "metadata": {},
   "outputs": [],
   "source": [
    "def hello():\n",
    "    print(\"Hello world!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "da1dcee9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello world!\n"
     ]
    }
   ],
   "source": [
    "hello()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "15f3777c",
   "metadata": {},
   "outputs": [],
   "source": [
    "def he():\n",
    "    name = input(\"请输入姓名\")\n",
    "    print(\"Hello\"+ name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "87e74079",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "请输入姓名杨洋老婆\n",
      "Hello杨洋老婆\n"
     ]
    }
   ],
   "source": [
    "he()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "75d3290c",
   "metadata": {},
   "outputs": [],
   "source": [
    "def hello_user(username):\n",
    "    print(\"你好\"+ username.title()+\"同学~\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "f75f0e60",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你好Cayhy同学~\n"
     ]
    }
   ],
   "source": [
    "hello_user(\"Cayhy\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "1975cac9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义函数\n",
    "def greet_user(username):    \n",
    "    \"\"\"显示简单的问候语，输入你的名字\"\"\"    \n",
    "    print(\"hello,\"+ username.title()+\"!\")         \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "256d1f88",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello,Ccathy!\n"
     ]
    }
   ],
   "source": [
    "# 调用函数：　username　= \"Cathy\"\n",
    "greet_user(\"Ccathy\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d3a9fecc",
   "metadata": {},
   "source": [
    "## 注意：\n",
    "* （1）在第一行定义函数中，不需要任何信息就能完成工作，因此括号是空的（即便如此，括号必不可少！）\n",
    "\n",
    "* 　(2）要调用函数，可以依次指定函数名以及括号括起的必要信息。在第五行代码中，因为此函数greet_uesr()括号中不需要任何信息，只需要输入greet_uesr（）即可。和预期效果一样，打印Hello！："
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8d9390b9",
   "metadata": {},
   "source": [
    "## 3.函数的参数\n",
    "> 1. 形式参数：\n",
    ">> 1. 定义函数时 写在 function_name(） 括号里面的参数\n",
    ">> 2. 在定义函数时，形式函数不占用空间\n",
    "> 2. 实际参数： \n",
    ">> 1. 调用函数时 写在 function_name() 括号里面的参数\n",
    ">> 2. 在使用函数时，形式函数 被 分配 空间，变为实际参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "1595a6ec",
   "metadata": {},
   "outputs": [],
   "source": [
    " def describe_pet(animal_type,pet_name):\n",
    "# 4     \"\"\"显示宠物信息\"\"\"\n",
    "    print(\"\\nI have a\" + animal_type + \".\")\n",
    "    print(\"My\" + animal_type + \"'s name is \"+pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "ee3ae83c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have adog.\n",
      "Mydog's name is Kaka.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"dog\",\"Kaka\") # \"dog\",\"Kaka\" 实际参数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1c2e967e",
   "metadata": {},
   "source": [
    "* 当函数具有多个参数时\n",
    "> 1. 位置参数\n",
    ">> 1. 形式参数有先后顺序，函数调用过程中应考虑参数的先后顺序，避免出现顺序错误的笑话\n",
    ">> 2. 调用参数过程中要考虑形式参数的个数\n",
    "> 2. 关键字参数\n",
    ">> 1. 调用函数时，通过赋值的方式传递给定义好的形参变量数据\n",
    ">> 2. 不考虑先后顺序，因为是指定变量赋值\n",
    "> 3. 默认参数\n",
    ">> 1. 在形式参数中，提前预先设置有个用户可能使用的参数值\n",
    ">> 2. 用户在使用/或调用参数时，可以省略不给默认参数赋值\n",
    ">> 3. 用户给默认参数赋值，将替换默认参数的值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "cce909d1",
   "metadata": {},
   "outputs": [],
   "source": [
    " def describe_pet(animal_type,pet_name):\n",
    "# 4     \"\"\"显示宠物信息\"\"\"\n",
    "    print(\"\\nI have a\" + animal_type + \".\")\n",
    "    print(\"My\" + animal_type + \"'s name is \"+pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "67f145dd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have adog.\n",
      "Mydog's name is Kaka.\n"
     ]
    }
   ],
   "source": [
    "# 在使用 describe_pet（） 函数时 需要考虑参数的位置，从而进行参数数据的输入（实参的调用）\n",
    "# 位置参数：\n",
    "describe_pet(\"dog\",\"Kaka\") # 要根据 形式参数的位置先后顺序 先写 animal_type再pet_name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "4384ff0b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have acat.\n",
      "Mycat's name is Kuangkuang.\n"
     ]
    }
   ],
   "source": [
    "# 关键字参数：\n",
    "describe_pet(animal_type=\"cat\",pet_name=\"kuangkuang\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "502d2cba",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 默认参数：\n",
    "def describe_pet(pet_name,animal_type=\"dog\"):\n",
    "# 4     \"\"\"显示宠物信息\"\"\"\n",
    "    print(\"\\nI have a\" + animal_type + \".\")\n",
    "    print(\"My\" + animal_type + \"'s name is \"+pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "30814495",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have adog.\n",
      "Mydog's name is Kaka.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"kaka\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b838ec93",
   "metadata": {},
   "source": [
    "> 1. 思考： 关键字参数（调用函数） 和 位置参数（调用函数） 是否可以一起使用？\n",
    ">> 1. positional argument follows keyword argument(位置参数<strong>均</strong>要放在关键字参数前面)\n",
    ">> 2. text1() got multiple values for argument 'x'(映射, 不能出现 multiple walues (多重值))\n",
    "> 2. 定义函数：默认参数(定义函数)和非默认参数（定义函数）的先后关系\n",
    ">> 1. 非默认参数<b>均</b>要放在默认参数前面\n",
    "* 以下为测试代码"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "64127ce8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# eg1\n",
    "def text1(x,y,z):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "721dcba8",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "positional argument follows keyword argument (<ipython-input-57-d2411b4e654d>, line 1)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-57-d2411b4e654d>\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m    text1(x= 2,3,z=4)\u001b[0m\n\u001b[1;37m               ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m positional argument follows keyword argument\n"
     ]
    }
   ],
   "source": [
    "text1(x= 2,3,z=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "2b8c12a1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "3\n",
      "5\n"
     ]
    }
   ],
   "source": [
    "text1(2,y=3,z=5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "2009b6a3",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "text1() got multiple values for argument 'x'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-58-cf56ac24595c>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mtext1\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mx\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m3\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0my\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: text1() got multiple values for argument 'x'"
     ]
    }
   ],
   "source": [
    "text1(2,x = 3,y = 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "16ebf8eb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# eg2\n",
    "def text1(x,z,y = 3):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "id": "f2eef384",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义了一个名字叫“search4vowels” 函数\n",
    "def search4vowels(word):\n",
    "    \"\"\"\n",
    "    打印文本中出现的元音字母\n",
    "    请输入你想要查询的文本内容\n",
    "    \"\"\"\n",
    "    vowels = set('aeiou')\n",
    "    found = vowels.intersection(set(word)) # 交集运算\n",
    "    print(found)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "id": "dc7dd4a8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'a'}\n"
     ]
    }
   ],
   "source": [
    "search4vowels(\"fdykjhfkjasj\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6e268f10",
   "metadata": {},
   "source": [
    "## 课本实践\n",
    "> 1. 总结函数的优势\n",
    "> 2. 预习课本第四章函数与模块\n",
    ">> 1. 完成课本元音字母实践\n",
    ">> 2. 浏览模块，创建模块和调用模块，了解PEP 8 python国际代码标准"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aff7a341",
   "metadata": {},
   "source": [
    "\n",
    "### 函数：完成 特定 功能的代码块，作为一个整体，对其进行特定的命名，该名字就代表函数\n",
    "##### 现实中：很多问题要通过一些工具进行处理 => 可以将工具提前生产出来并命名\n",
    "#### 通过名字就可以找到工具 => 使用工具来解决问题\n",
    "### 函数的优点：\n",
    "* 1. 避免代码的冗余\n",
    "* 2. 让程序代码结构更加清晰\n",
    "* 3. 让代码具有复用性，便于维护\n",
    "\n",
    "### 函数的四部分\n",
    "\n",
    "* 1. 函数名：使用该函数的依据\n",
    "* 2. 函数体：完成功能的代码块\n",
    "* 3. 返回值：功能完成的反馈结果\n",
    "* 4. 参数：完成功能需要的条件信息\n",
    "\n",
    "### 定义函数的语法：通过def关键字来定义\n",
    "def get_water(water, money):\n",
    "    print('收入你的%d元钱')\n",
    "    print('给你%s水种')\n",
    "    return '矿泉水'\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ba0f7aca",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
